home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
015
/
canjetdl.asm
< prev
next >
Wrap
Assembly Source File
|
1986-12-07
|
12KB
|
374 lines
PAGE ,132
TITLE CANJETDL - Print Screen Utility
;*** CANJETDL - Print Screen Utility
;
; CANJETDL is a print screen utility. It intercepts INT 5 from
; the BIOS (generated when <Print Screen> is struck), and prints
; the contents of the screen onto the PRN device.
;
; To execute:
;
; CANJETDL
;
; To activate:
;
; Press <Print Screen>
;
; OR, if using Mouse Systems' PC PAINT, execute CANJETDL before PC PAINT
; then, use the normal program procedures for printing a picture.
;
; Once CANJETDL has been executed, it remains permanently in RAM and
; does not need to be executed again.
;
;- Modified Aug 86 by SRN - Text dump to graphics.
; Modified again by Wayne D. Markel for IBM EGA
;- Canon PJ-1080A Inkjet graphics dump.
;- Code has been taken from various sources and been modified to suit.
;
; I wrote numerous versions of this program.
; This version was written specifically for use with IBM Drawing
; Assistant. It can only be invoked by using the PRINT SCREEN key,
; and therefore reads only the portion of the screen that contains the
; picture, not the border and icons.
;
; This version also rotates the picture 90 degrees and doubles up on
; the pixels in order to get a larger picture.
; NOTE: This is my first ever attempt at assembler programming so
; any comments for improvement would be appreciated.
; Wayne D. Markel
; 655 Carnathan Ct.
; Ft. Walton Beach, Florida 32548
; 904-862-5417
; Compuserve ID 71330,552
FALSE = 0
TRUE = NOT FALSE
; The next 2 switches should be set to TRUE and TRUE for:
COLUMNS = 80 ; Characters/line
page
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
ORG 100H
;* Entry point
;
BEGIN:
JMP NEAR PTR START
;* INT 5 handler
;
INT_5:
PUSH DS ; Save his data segment
PUSH AX
MOV CS:INT_SP,SP
MOV CS:INT_SS,SS ; Save his stack
MOV AX,CS
MOV SS,AX ; Set local stack
MOV SP,OFFSET INT_STACK
STI ; Now allow interrupts to come in
PUSH ES
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
MOV DS,AX
MOV ES,AX ; Set up my segments
CALL CANJET
POP DI
POP SI
POP DX
POP CX
POP BX
POP ES
CLI ; INTs off while messing around
MOV AX,CS:INT_SP
MOV SP,AX
MOV AX,CS:INT_SS ; Restore his stack
MOV SS,AX
POP AX
POP DS
IRET ; Back to BIOS
INT_SS DW 0 ; Saved stack values
INT_SP DW 0
INT_CX DW 0 ; Current X location
INT_CY DW 0 ; Current Y location
MYCHR DW 0 ; Character at position
MYLINE DB 82 DUP (?) ; Line buffer
LINES DW 0 ; Number of lines valid on screen
BLUE_BUFFER DB 80 DUP(?)
GREEN_BUFFER DB 80 DUP(?)
RED_BUFFER DB 80 DUP(?)
DosVersMsg db "ATTR: Needs DOS 2.0 +$"
LOAD_BUFFER DB ?
ROW DW ?
COLUMN DW ?
NO_OF_BYTES EQU 50H
DW 128 DUP (?)
INT_STACK LABEL NEAR ; Internal stack
CANJET PROC NEAR
;------------------------------------------------------------------------------
; PROCEDURE TO READ AN EGA MODE 16 SCREEN, ROTATE IT 90 DEGREES CLOCKWISE,
; DOUBLE THE DOT OUTPUT FROM 640X350 TO 1280X700 AND PRINT IT ON A CANON
; PJ1080A
;------------------------------------------------------------------------------
;This code for checking DOS version came from PC Magazine
Mov AH, 30h ; Check for DOS Version
Int 21h ; through DOS call
Cmp AL, 2 ; See if it's 2.0 or above
Jae DosVersOK ; If so, continue
Mov DX, Offset DosVersMsg ; Error message
ErrorExit:
Mov AH, 9 ; Print String function call
Int 21h ; Do it
Int 20h ; And exit prematurely
DosVersOK:
;-------------------------------------------------------------------------------
; READ A WINDOW, ONE DOT AT A TIME, RETURNING THE VALUE IN AL
;-------------------------------------------------------------------------------
MOV COLUMN,92D ;INITIALIZE COLUMN COUNTER
NEWCOLUMN:
MOV LOAD_BUFFER,80H ;INITIALIZE THIS VARIABLE WHICH IS USED
MOV ROW,337D ;SET ROW POINTER TO BOTTOM OF WINDOW
;------------------------------------------------------------------------------
; ZERO OUT BUFFERS AT BEGINNING OF EACH ROW
;------------------------------------------------------------------------------
MOV CX,240D
MOV BX,00 ;SET OFFSET POINTER TO ZERO
ZERO: MOV [BLUE_BUFFER+BX],00 ;PUT ZERO IN BYTE OF RED_BUFFER
INC BX
LOOP ZERO
;------------------------------------------------------------------------------
; READ A DOT AT COLUMN=CX ROW=DX
; RETURN VALUE OF PIXEL IN AL
;------------------------------------------------------------------------------
MOV BX,0 ;INITIALIZE POINTER FOR BUFFERS
LINE: MOV CX,COLUMN ;SET CX TO CURRENT COLUMN
MOV DX,ROW ;SET DX TO CURRENT ROW
MOV AH,0DH ;READ DOT FUNCTION
INT 10H
MOV DH,LOAD_BUFFER ;SETUP DH TO TURN ON CORRECT BIT WHEN
; ORed WITH A BYTE IN ONE OF THE BUFFERS
;------------------------------------------------------------------------------
; In order to get a picture 8.25X15.0 inches on the CANON, it is necessary
; to write each pixel FOUR times. The EGA operates in 640X350 pixel
; mode. So the program will load the value of the pixel into a buffer
; TWICE and print each buffer TWICE. This will
; produce a picture on paper 1280 by 700 pixels in size.
;------------------------------------------------------------------------------
CALL LOAD_BUFFERS
CALL LOAD_BUFFERS
;------------------------------------------------------------------------------
; Ok, that doubled up on the pixels, now it's time to DEC the ROW
; counter to read the next pixel
;------------------------------------------------------------------------------
DEC WORD PTR [ROW] ;DECREMENT THE ROW COUNTER
;------------------------------------------------------------------------------
; CHECK TO SEE IF AT TOP OF THE WINDOW
;------------------------------------------------------------------------------
CMP WORD PTR [ROW],18D ;TEST IF ABOVE TOP OF WINDOW
JGE LINE ;NO...READ ANOTHER DOT
CALL OUTPUT_BUFFERS ;YES, OUTPUT ONE LINE TO CANONJET
CALL OUTPUT_BUFFERS ;OUTPUT SECOND LINE
INC WORD PTR [COLUMN] ;INCREMENT COLUMN NUMBER
CMP WORD PTR [COLUMN],548D ;AT RIGHT EDGE OF WINDOW?
JL NEWCOLUMN ;NO, READ ANOTHER COLUMN OF DOTS
RET ;YES..HAVE READ ALL OF WINDOW, SO EXIT
;-------------------------------------------------------------------------------
; SUBROUTINE TO LOAD BUFFERS
;-------------------------------------------------------------------------------
LOAD_BUFFERS PROC NEAR
MOV AH,AL ;PUT THE VALUE FROM THE READ_DOT BIOS
; CALL INTO AH FOR FURTHER MANIPULATION
SHR AH,1 ;PUSH THE LSB INTO THE BIT BUCKET
;------------------------------------------------------------------------------
; IF IT'S A "1", THEN TURN ON THE
; CORRESPONDING BIT IN THE CURRENT
; BYTE OF THE BLUE BUFFER
;------------------------------------------------------------------------------
JNC GREEN ;IF IT'S A 0 CHECK THE GREEN BIT
LOAD_BLUE_BUFFER:
OR BYTE PTR [BLUE_BUFFER+BX],DH ;TURN ON A BIT IN BUFFER
GREEN: SHR AH,1 ;SHIFT RIGHT ONE MORE TIME
; TO SEE IF THE 2 BIT IS ON
;IF YES, PUT A BIT IN THE GREEN BUFFER
JNC RED ;IF NO, CHECK THE RED BIT
LOAD_GREEN_BUFFER:
OR BYTE PTR [GREEN_BUFFER+BX],DH
RED: SHR AH,1 ;SHIFT ONE MORE TIME TO CHECK THE 4 BIT
JNC END_LOAD_BUFFER ;IF NOT SET JUMP TO END_LOAD_BUFFER
LOAD_RED_BUFFER:
OR BYTE PTR[RED_BUFFER+BX],DH ;SINCE THE 4 BIT IS SET, LOAD...
; TO THE BUFFER
END_LOAD_BUFFER:
SHR DX,1
MOV LOAD_BUFFER,DH ;SHR THE VARIABLE, "LOAD_BUFFER"
CMP DH,00 ;HAVE WE READ 8 DOTS YET?
JNZ SAME_BYTE ;NO, READ NEXT DOT
MOV LOAD_BUFFER,80H ;RESET MSB OF LOAD_BUFFER
MOV DH,LOAD_BUFFER ;SAME FOR DH
;-------------------------------------------------------------------------------
; AFTER STUFFING 8 DOTS INTO THE BUFFER, INCREMENT THE BUFFER OFFSET POINTER
;-------------------------------------------------------------------------------
INC BX ;BUMP POINTER FOR BUFFERS
SAME_BYTE:
RET
LOAD_BUFFERS ENDP
;------------------------------------------------------------------------------
OUTPUT_BUFFERS PROC NEAR
;-------------------------------------------------------------------------------
; SET CANONJET TO GRAPHICS MODE...
; ...THEN OUTPUT ONE ROW OF DOTS TO THE CANONJET.
; NOTE: TWO ROWS OF DOTS MUST BE SENT BEFORE ANY PRINTER ACTION OCCURS
;
;-------------------------------------------------------------------------------
MOV AH,5 ;SET DOS FUNCTION TO 5 FOR PRINT
;TER OUTPUT
MOV DL,01BH ;SEND
INT 21H ;ESCAPE CHARACTER
MOV DL,058H ;THEN "X" CHARACTER
INT 21H
MOV DL,NO_OF_BYTES ;GET READY FOR 10 BYTES OF DATA
INT 21H
;------------------------------------------------------------------------------
; OUTPUT (NO_OF_BYTES) FROM THE RED_BUFFER
;------------------------------------------------------------------------------
MOV BX,0 ;SET OFFSET IN BUFFER TO ZERO
RED_OUT: MOV DL,[RED_BUFFER+BX] ;PUT BYTE IN DL FOR OUTPUT TO
;PRINTER
INT 21H ;DO IT.
INC BX ;MOVE OVER TO NEXT BYTE IN
; BUFFER
CMP BX,NO_OF_BYTES
JL RED_OUT ;READ ANOTHER BYTE UNTIL 80
; HAVE BEEN READ.
;------------------------------------------------------------------------------
; OUTPUT (N0_OF_BYTES) FROM THE GREEN_BUFFER
;------------------------------------------------------------------------------
MOV BX,0
GREEN_OUT: MOV DL,[GREEN_BUFFER+BX]
INT 21H
INC BX
CMP BX,NO_OF_BYTES
JL GREEN_OUT
;------------------------------------------------------------------------------
; OUTPUT (NO_OF_BYTES) FROM THE BLUE_BUFFER
;------------------------------------------------------------------------------
MOV BX,0
BLUE_OUT: MOV DL,[BLUE_BUFFER+BX]
INT 21H
INC BX
CMP BX,NO_OF_BYTES
JL BLUE_OUT
;------------------------------------------------------------------------------
; ONE LINE OF DOTS HAVE BEEN OUTPUT TO THE CANONJET PRINT BUFFER
;------------------------------------------------------------------------------
RET
OUTPUT_BUFFERS ENDP
;-------------------------------------------------------------------------------
RET ;NEAR RETURN TO DOS
CANJET ENDP
INT_END LABEL NEAR
;* Main entry point
;
START:
MOV SP,OFFSET INT_STACK ; Good place for it
PUSH DS
XOR AX,AX
MOV DS,AX ; Clear DS
MOV SI,5*4 ; SI points to interrupt
CLI
MOV WORD PTR [SI],OFFSET INT_5
MOV WORD PTR [SI+2],CS ; Set my interrupt vector
STI
POP DS
MOV DX,OFFSET INT_END ; LWA of resident portion
; MOV AH,31H ;FUNCTION FOR STAY RESIDENT
; MOV AL,1 ;RETURN CODE FOR COMMAND
; MOV DX,5D ;RESERVE 1.5K MEMORY
; INT 21H
INT 27H
CODE ENDS
END BEGIN